/*
 * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Apache-2.0
 */

// 该文件实现了USB大容量存储设备类(MSC)，允许通过拖放UF2格式文件来烧录ESP设备
// 主要功能包括初始化虚拟磁盘、处理USB MSC协议命令、解析UF2文件并执行烧录操作

#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
#include "esp_log.h"
#include "msc.h"
#include "esp_loader.h"
#include "serial.h"
#include "sdkconfig.h"
#include "driver/gpio.h"
#include "esp_io.h"
#include "esp_timer.h"
// 定义FAT16文件系统相关参数
#define KB(x)                   ((x) * 1024)
#define FAT_CLUSTERS            KB(6)                                    // 6KB簇数量
#define FAT_SECTORS_PER_CLUSTER 8                                        // 每簇扇区数
#define FAT_SECTORS             (FAT_CLUSTERS * FAT_SECTORS_PER_CLUSTER) // 总扇区数
#define FAT_SECTOR_SIZE         512                                      // 每扇区字节数
#define FAT_ROOT_SECTORS        2                                        // 根目录扇区数
#define FAT_ROOT_ENTRY_SIZE     32                                       // 根目录条目大小
#define FAT_VOLUME_NAME_SIZE    11                                       // 卷名大小

#define SYSTEM_PROVIDED_FIFE_NUM 2 // 系统自带的文件个数（README.TXT、INDEX.HTM）
#define BOOTUF2_INDEX_URL        "https://www.espressif.com.cn/"
#define MIN(a, b)                (((a) < (b)) ? (a) : (b))

// 根目录条目数计算
#define FAT_ROOT_ENTRIES    (FAT_ROOT_SECTORS * FAT_SECTOR_SIZE / FAT_ROOT_ENTRY_SIZE)
#define FAT16_CLUSTER_BYTES 2                                                      // FAT表每簇占用字节数
#define FAT_TABLE_SECTORS   (FAT_CLUSTERS * FAT16_CLUSTER_BYTES / FAT_SECTOR_SIZE) // FAT表扇区数
#define FAT_BOOT_SECTORS    1                                                      // 引导扇区数
void tud_msc_write10_complete_cb(void);
// FAT16引导扇区结构体
typedef struct __attribute__((__packed__)) {
    uint8_t jump_instructions[3]; // 跳转指令
    uint8_t oem_name[8];          // OEM名称
    uint16_t bytes_per_sector;    // 每扇区字节数
    // BIOS参数块(25字节)
    uint8_t sectors_per_cluster; // 每簇扇区数
    uint16_t reserved_sectors;   // 保留扇区数
    uint8_t fat_table_copies;    // FAT表副本数
    uint16_t root_entries;       // 根目录条目数
    uint16_t no_small_sectors;   // 小扇区数
    uint8_t media_type;          // 介质类型
    uint16_t fat_table_sectors;  // FAT表扇区数
    uint16_t sectors_per_track;  // 每磁道扇区数
    uint16_t heads;              // 磁头数
    uint32_t hidden_sectors;     // 隐藏扇区数
    uint32_t large_sectors;      // 大扇区数
    // 扩展BIOS参数块(26字节)
    uint8_t physical_disco_no;            // 物理磁盘号
    uint8_t current_head;                 // 当前磁头
    uint8_t signature;                    // 签名
    uint32_t serial_no;                   // 序列号
    uint8_t volume[FAT_VOLUME_NAME_SIZE]; // 卷标
    uint8_t system_id[8];                 // 系统ID

    uint8_t bootstrap_code[448]; // 引导代码
    uint16_t end_marker;         // 结束标记(0xAA55)
} msc_boot_sector_t;

static const char *TAG = "bridge_msc"; // 日志标签

// 静态断言，确保参数符合FAT16规范
_Static_assert(FAT_SECTORS == (FAT_SECTORS & 0xFFFF), "Large sectors should be used instead of small ones");
_Static_assert(FAT_SECTOR_SIZE == (FAT_SECTOR_SIZE & 0xFFFF), "FAT Sector Size must fit into a 16-bit field");
_Static_assert(FAT_SECTORS_PER_CLUSTER == (FAT_SECTORS_PER_CLUSTER & 0xFF), "FAT Sectors per Cluster must fit into a 8-bit field");
_Static_assert(FAT_ROOT_ENTRIES == (FAT_ROOT_ENTRIES & 0xFFFF), "FAT ROOT entries must fit into a 16-bit field");
_Static_assert(FAT_TABLE_SECTORS == (FAT_TABLE_SECTORS & 0xFFFF), "FAT table sectors must fit into a 16-bit field");
_Static_assert(FAT_BOOT_SECTORS == (FAT_BOOT_SECTORS & 0xFFFF), "FAT boot sectors must fit into a 16-bit field");
_Static_assert(sizeof(msc_boot_sector_t) == FAT_SECTOR_SIZE, "The boot sector has incorrect size!");
_Static_assert(strlen(BRIDGE_MSC_VOLUME_LABEL) <= FAT_VOLUME_NAME_SIZE, "BRIDGE_MSC_VOLUME_LABEL is too long");

// 初始化引导扇区数据
static msc_boot_sector_t msc_disk_boot_sector = {
    .jump_instructions = { 0xEB, 0x3C, 0x90 },               // 跳转指令
    .oem_name = { 'm', 'k', 'f', 's', '.', 'f', 'a', 't' },  // OEM名称
    .bytes_per_sector = FAT_SECTOR_SIZE,                     // 每扇区512字节
    .sectors_per_cluster = FAT_SECTORS_PER_CLUSTER,          // 每簇8扇区
    .reserved_sectors = FAT_BOOT_SECTORS,                    // 保留1个引导扇区
    .fat_table_copies = 1,                                   // 1个FAT表副本
    .root_entries = FAT_ROOT_ENTRIES,                        // 根目录条目数
    .no_small_sectors = FAT_SECTORS,                         // 总扇区数
    .media_type = 0xF8,                                      // 硬盘介质类型
    .fat_table_sectors = FAT_TABLE_SECTORS,                  // FAT表扇区数
    .sectors_per_track = 0,                                  // 未使用
    .heads = 0,                                              // 未使用
    .hidden_sectors = 0,                                     // 无隐藏扇区
    .large_sectors = 0,                                      // 未使用大扇区
    .physical_disco_no = 0x80,                               // 硬盘编号从0x80开始
    .current_head = 0,                                       // FAT未使用
    .signature = 0x29,                                       // Windows需要0x28或0x29
    .serial_no = 0x563d0c93,                                 // 随机生成的序列号
    .volume = { ' ' },                                       // 卷标初始化为空格
    .system_id = { 'F', 'A', 'T', '1', '6', ' ', ' ', ' ' }, // 系统ID

    // 引导代码 - 显示非启动磁盘提示信息 /*磁盘实际是虚拟的，不需要真正启动*/
    .bootstrap_code = {
        0x0e, 0x1f, 0xbe, 0x5b, 0x7c, 0xac, 0x22, 0xc0, 0x74, 0x0b, 0x56, 0xb4, 0x0e, 0xbb, 0x07, 0x00, 0xcd, 0x10, 0x5e,
        0xeb, 0xf0, 0x32, 0xe4, 0xcd, 0x16, 0xcd, 0x19, 0xeb, 0xfe, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x6e,
        0x6f, 0x74, 0x20, 0x61, 0x20, 0x62, 0x6f, 0x6f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x2e,
        0x20, 0x20, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x61, 0x20, 0x62,
        0x6f, 0x6f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x70, 0x70, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x0d,
        0x0a, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x74,
        0x72, 0x79, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e, 0x20, 0x2e, 0x2e, 0x2e, 0x20, 0x0d, 0x0a, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0 },
    .end_marker = 0xAA55, // 引导扇区结束标记
};

// FAT16表数据
static const uint8_t msc_disk_fat_table_sector0[] = {
    // 簇 0 和簇 1 (保留)
    0xF8, 0xFF, // 簇 0: 介质描述符 (固定值)
    0xFF, 0xFF, // 簇 1: FAT 保留区 (固定值)

    // 文件分配表
    // 簇 2: READM文件 (起始簇)
    0xFF, 0xFF, // 簇 2: 文件结束标记 (0xFFFF 表示文件结束)

    // 簇 3: Index文件 (起始簇)
    0xFF, 0xFF, // 簇 3: 文件结束标记 (0xFFFF 表示文件结束)
};

// README文件内容
static const uint8_t msc_disk_readme_sector0[] =
    "Use 'idf.py uf2' to generate an UF2 binary. Drop the generated file into this disk in order to flash the device. \
\r\n";
const char file_IDEX[] = {
    // 重定向到配置URL的HTML文件（INDEX.HTM）
    "<!doctype html>\n"
    "<html>"
    "<body>"
    "<script>\n"
    "location.replace(\"" BOOTUF2_INDEX_URL "\");\n" // 重定向到配置的URL
    "</script>"
    "</body>"
    "</html>\n"
};
#define MSC_INDEX_SIZE  (sizeof(file_IDEX) - 1)               // IDEX文件大小
#define MSC_README_SIZE (sizeof(msc_disk_readme_sector0) - 1) // README文件大小
#define GET_BYTE(n, b)  (((n) >> ((b) * 8)) & 0xFF)
_Static_assert(MSC_README_SIZE < FAT_SECTOR_SIZE, "Only the first sector of the README is stored in RAM");

// 根目录扇区数据
static uint8_t msc_disk_root_directory_sector0[] = {
    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 卷标
    0x08,                                                  // 属性字节(卷标位设置)
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,              // 创建和修改时间日期
    0, 0,                                                  // FAT表中的起始簇
    0, 0, 0, 0,                                            // 大小
    // README文件条目
    'R', 'E', 'A', 'D', 'M', 'E', ' ', ' ', 'T', 'X', 'T',                                                                  // 文件名
    0x01,                                                                                                                   // 属性字节(只读位设置)
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                                                                               // 创建和修改时间日期
    0x02, 0,                                                                                                                // FAT表中的起始簇(簇2)
    GET_BYTE(MSC_README_SIZE, 0), GET_BYTE(MSC_README_SIZE, 1), GET_BYTE(MSC_README_SIZE, 2), GET_BYTE(MSC_README_SIZE, 3), // 文件大小
    // 项目链接
    //todo miduo 先虚拟一个
    'I', 'N', 'D', 'E', 'X', ' ', ' ', ' ', 'H', 'T', 'M',                                                              // 文件名
    0x01,                                                                                                               // 属性字节(只读位设置)
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                                                                           // 创建和修改时间日期
    0x03, 0,                                                                                                            // FAT表中的起始簇(簇2)
    GET_BYTE(MSC_INDEX_SIZE, 0), GET_BYTE(MSC_INDEX_SIZE, 1), GET_BYTE(MSC_INDEX_SIZE, 2), GET_BYTE(MSC_INDEX_SIZE, 3), // 文件大小
};

//miduo
uint16_t bootuf2_get_sector_size(void)
{
    return FAT_SECTOR_SIZE;
}

uint32_t bootuf2_get_sector_count(void)
{
    return FAT_SECTORS;
}

// 定义磁盘区域划分
#define FIRST_FAT_SECTOR    FAT_BOOT_SECTORS                                                           // 第一个FAT表扇区
#define FIRST_ROOT_SECTOR   (FIRST_FAT_SECTOR + FAT_TABLE_SECTORS)                                     // 第一个根目录扇区
#define FIRST_README_SECTOR (8 + FIRST_ROOT_SECTOR + FAT_ROOT_SECTORS)                                 // 第一个README扇区
#define FIRST_ELSE_SECTOR   (FIRST_README_SECTOR + SYSTEM_PROVIDED_FIFE_NUM * FAT_SECTORS_PER_CLUSTER) // 第一个其他扇区
#define IS_LBA_BOOT(lba)    ((lba) < FIRST_FAT_SECTOR)                                                 // 是否为引导扇区
#define IS_LBA_FAT(lba)     ((lba) >= FIRST_FAT_SECTOR && (lba) < FIRST_ROOT_SECTOR)                   // 是否为FAT表扇区
#define IS_LBA_ROOT(lba)    ((lba) >= FIRST_ROOT_SECTOR && (lba) < FIRST_README_SECTOR)                // 是否为根目录扇区
#define IS_LBA_README(lba)  ((lba) >= FIRST_README_SECTOR && (lba) < FIRST_ELSE_SECTOR)                // 是否为README扇区
#define IS_LBA_ELSE(lba)    ((lba) >= FIRST_ELSE_SECTOR)                                               // 是否为其他扇区

// 读取磁盘扇区（模拟FAT16文件系统）
/*
* param: start_sector 起始扇区号
* param: buff 读出数据缓存
* param: sector_count 扇区数
* return: 0 成功，其他失败
*/
int boot2uf2_read_sector(uint32_t start_sector, uint8_t *buff, uint32_t sector_count)
{
    //ESP_LOGD(TAG, "boot2uf2_read_sector() invoked, start_sector=%" PRId32 ", sector_count=%" PRId32, start_sector, sector_count);
    uint32_t size = 0;

    uint8_t *addr = NULL;
    //memset(buff, 0, FAT_SECTOR_SIZE); // 清空缓冲区
    //ESP_EARLY_LOGI("MdLink", "call boot2uf2_read_sector() start_sector:%d,sector_count:%d", start_sector, sector_count);
    while (sector_count) {
        memset(buff, 0, FAT_SECTOR_SIZE);
        // 根据start_sector确定读取哪个区域
        if (IS_LBA_BOOT(start_sector)) {
            //ESP_EARLY_LOGI("MdLink", "enter boot sector");
            addr = (uint8_t *)&msc_disk_boot_sector; // 引导扇区
            size = sizeof(msc_disk_boot_sector);
        } else if (start_sector == FIRST_FAT_SECTOR) {
            //ESP_EARLY_LOGI("MdLink", "enter fat table sector");
            addr = (uint8_t *)msc_disk_fat_table_sector0; // FAT表
            size = sizeof(msc_disk_fat_table_sector0);
        } else if (start_sector == FIRST_ROOT_SECTOR) {
            //ESP_EARLY_LOGI("MdLink", "enter root directory sector");
            addr = (uint8_t *)msc_disk_root_directory_sector0; // 根目录

            size = sizeof(msc_disk_root_directory_sector0);
        } else if (start_sector >= FIRST_README_SECTOR) {
            //ESP_EARLY_LOGI("MdLink", "enter fife sector");
            // 处理数据区扇区（文件内容）
            /*通过start_sector算出簇号*/
            //先算出数据区开始扇区
            uint32_t sector_relative = start_sector - FIRST_README_SECTOR;
            //再算出簇号
            // 根据扇区位置计算对应的文件簇号：
            // 1. 扇区偏移 / 每簇扇区数 → 得到簇内偏移量
            // 2. FAT文件系统的数据簇从2开始编号（簇0和簇1保留）
            // 3. 因此实际簇号 = 2 + 簇索引
            int fid = 2 + sector_relative / FAT_SECTORS_PER_CLUSTER;
            if (fid == 2) {
                //README文件
                addr = (uint8_t *)msc_disk_readme_sector0; // README文件
                size = sizeof(msc_disk_readme_sector0);
            } else if (3 == fid) {
                //INDEX文件
                //README文件
                addr = (uint8_t *)file_IDEX; // README文件
                size = sizeof(file_IDEX);
            }

        } // 其他扇区不在RAM中保存

        //都是不超过一个扇区大小
        if (size > FAT_SECTOR_SIZE)
            size = FAT_SECTOR_SIZE;
        //ESP_EARLY_LOGI("MdLink", "memcpy size:%d", size);
        memcpy(buff, addr, size); // 拷贝文件内容
        start_sector++;
        sector_count--;
        buff += FAT_SECTOR_SIZE;
    }
    return 0;
}

// UF2文件格式相关定义
#define UF2_BLOCK_SIZE            512        // UF2块大小
#define UF2_DATA_SIZE             476        // UF2数据大小
#define UF2_MD5_SIZE              24         // MD5大小
#define UF2_FIRST_MAGIC           0x0A324655 // 第一个魔数
#define UF2_SECOND_MAGIC          0x9E5D5157 // 第二个魔数
#define UF2_FINAL_MAGIC           0x0AB16F30 // 最终魔数
#define UF2_FLAG_FAMILYID_PRESENT 0x00002000 // 家族ID存在标志
#define UF2_FLAG_MD5_PRESENT      0x00004000 // MD5存在标志

// UF2块结构体
typedef struct
{
    uint32_t magic0;             // 第一个魔数
    uint32_t magic1;             // 第二个魔数
    uint32_t flags;              // 标志位
    uint32_t addr;               // 目标地址
    uint32_t payload_size;       // 有效载荷大小
    uint32_t block_no;           // 块编号
    uint32_t blocks;             // 总块数
    uint32_t chip_id;            // 芯片ID
    uint8_t data[UF2_DATA_SIZE]; // 数据
    uint32_t magic3;             // 最终魔数
} uf2_block_t;

#define UF2_ESP8266_ID 0x7eab61ed // ESP8266芯片ID

// 根据芯片ID返回芯片名称
static const char *chipid_to_name(const uint32_t id)
{
    // ID参考: https://github.com/Microsoft/uf2
    switch (id) {
        case UF2_ESP8266_ID:
            return "ESP8266";
        case 0x1c5f21b0:
            return "ESP32";
        case 0xbfdd4eee:
            return "ESP32-S2";
        case 0xd42ba06c:
            return "ESP32-C3";
        case 0xc47e5767:
            return "ESP32-S3";
        case 0x2b88d29c:
            return "ESP32-C2";
        case 0x332726f6:
            return "ESP32-H2";
        case 0x540ddf62:
            return "ESP32-C6";
        case 0x3d308e94:
            return "ESP32-P4";
        case 0xf71c0343:
            return "ESP32-C5";
        case 0x77d850c4:
            return "ESP32-C61";
        case 0xb6dd00af:
            return "ESP32-H21";
        case 0x9e0baa8a:
            return "ESP32-H4";
        default:
            return "unknown";
    }
}

// 缓冲区大小定义
#define BUFFER_SIZE      KB(16) // 缓冲区大小16KB
#define FLASH_BLOCK_SIZE KB(4)  // Flash块大小4KB

// 烧录相关波特率定义
#define MSC_FLASH_HIGH_BAUDRATE    230400 // 高速波特率
#define MSC_FLASH_DEFAULT_BAUDRATE 115200 // 默认波特率

volatile static int msc_last_block_written = -1; // 最后写入的块编号
static esp_timer_handle_t reset_timer;           // 复位定时器句柄

// 改变波特率函数
static bool msc_change_baudrate(const uint32_t chip_id, const uint32_t baud)
{
    if (chip_id == UF2_ESP8266_ID) { // ESP8266不支持波特率改变
        return true;
    }
    // 改变波特率并设置串口
    return (esp_loader_change_baudrate(baud) == ESP_LOADER_SUCCESS) && serial_set_baudrate(baud);
}

// Flash数据写入函数
static esp_loader_error_t flash_data(uint32_t addr, uint8_t *data, uint32_t datalen)
{
    const uint32_t block_size = KB(4); // ROM Flash最大块大小
    if (esp_loader_flash_start(addr, datalen, block_size) != ESP_LOADER_SUCCESS) {
        ESP_LOGE(TAG, "Erasing flash failed at addr %" PRId32 " of length %" PRId32, addr, datalen);
        return ESP_LOADER_ERROR_FAIL;
    }

    // 分块写入数据
    while (datalen > 0) {
        uint32_t bytes_to_write = MIN(datalen, block_size);
        ESP_LOGD(TAG, "Writing flash at addr %" PRId32 " of length %" PRId32, addr, bytes_to_write);
        if (esp_loader_flash_write(data, bytes_to_write) != ESP_LOADER_SUCCESS) {
            ESP_LOGE(TAG, "Writing flash failed at addr %" PRId32 " of length %" PRId32, addr, datalen);
            return ESP_LOADER_ERROR_FAIL;
        }
        datalen -= bytes_to_write;
        data += bytes_to_write;
        addr += bytes_to_write;
    }
    return ESP_LOADER_SUCCESS;
}

// 处理数据函数 - 管理缓冲区并执行Flash写入
static bool handle_data(uint32_t addr, uint8_t *data, uint32_t datalen, bool flush_buffer)
{
    static uint8_t buffer[BUFFER_SIZE];   // 静态缓冲区
    static uint32_t last_written_pos = 0; // 最后写入位置
    static uint32_t aligned_addr = 0;     // 对齐地址

    if (flush_buffer) {
        // 如果有数据在缓冲区中，填充到块边界并写入
        if (last_written_pos > 0) {
            uint32_t end_addr = aligned_addr + last_written_pos;
            uint32_t pad_size = (FLASH_BLOCK_SIZE - (end_addr % FLASH_BLOCK_SIZE)) % FLASH_BLOCK_SIZE;

            // 如果需要填充，从Flash读取现有数据
            if (pad_size > 0) {
                if (esp_loader_flash_read(buffer + last_written_pos, end_addr, pad_size) != ESP_LOADER_SUCCESS) {
                    return false;
                }
                last_written_pos += pad_size;
            }

            // 写入完整块
            if (flash_data(aligned_addr, buffer, last_written_pos) != ESP_LOADER_SUCCESS) {
                return false;
            }
            last_written_pos = 0;
        }
        return true;
    }

    // 如果缓冲区为空，检查地址是否对齐到块大小
    if (last_written_pos == 0) {
        aligned_addr = addr & ~(FLASH_BLOCK_SIZE - 1);
        if (addr != aligned_addr) {
            uint32_t bytes_to_read = addr - aligned_addr;
            if (esp_loader_flash_read(buffer, aligned_addr, bytes_to_read) != ESP_LOADER_SUCCESS) {
                return false;
            }
            last_written_pos = bytes_to_read;
        }
    }

    // 处理缓冲区溢出 - 写入当前缓冲区并继续处理剩余数据
    uint32_t remaining_space = BUFFER_SIZE - last_written_pos;
    if (datalen > remaining_space) {
        uint32_t bytes_to_copy = remaining_space;
        memcpy(buffer + last_written_pos, data, bytes_to_copy);

        if (flash_data(aligned_addr, buffer, BUFFER_SIZE) != ESP_LOADER_SUCCESS) {
            return false;
        }

        // 更新剩余需要写入的数据
        datalen -= bytes_to_copy;
        data += bytes_to_copy;
        addr += bytes_to_copy;
        last_written_pos = 0;

        // 递归处理剩余数据
        return handle_data(addr, data, datalen, false);
    }

    // 添加新数据到缓冲区
    memcpy(buffer + last_written_pos, data, datalen);
    last_written_pos += datalen;

    return true;
}

// 初始化Flash函数
static bool init_flash(uint32_t chip_id)
{
    //serial_set(false); // 禁用串口

    // 设置默认波特率
    if (!serial_set_baudrate(MSC_FLASH_DEFAULT_BAUDRATE)) {
        ESP_LOGW(TAG, "BRIDGE UART failed to change baudrate to %d", MSC_FLASH_DEFAULT_BAUDRATE);
        return false;
    }
    //ESP_EARLY_LOGI("MdLink", "bug place 4");

    // 连接目标设备
    esp_loader_connect_args_t connect_config = ESP_LOADER_CONNECT_DEFAULT();
    if (esp_loader_connect(&connect_config) != ESP_LOADER_SUCCESS) {
        ESP_LOGE(TAG, "ESP LOADER connection failed!");
        return false;
    }
    ESP_LOGD(TAG, "ESP LOADER connection success!");
    //ESP_EARLY_LOGI("MdLink", "bug place 5");

    // 切换到高速波特率
    if (!msc_change_baudrate(chip_id, MSC_FLASH_HIGH_BAUDRATE)) {
        ESP_LOGE(TAG, "Failed to change baudrate to %d", MSC_FLASH_HIGH_BAUDRATE);
        return false;
    }
    ESP_LOGD(TAG, "Baudrate changed to %d", MSC_FLASH_HIGH_BAUDRATE);

    return true;
}

// 完成Flash烧录函数
static bool finish_flash(void)
{
    // 刷新缓冲区中剩余的数据
    if (!handle_data(0, NULL, 0, true)) {
        ESP_LOGE(TAG, "Failed to flush buffer");
        return false;
    }

    // 恢复默认波特率
    if (!serial_set_baudrate(MSC_FLASH_DEFAULT_BAUDRATE)) {
        ESP_LOGW(TAG, "ESP LOADER cannot change baudrate to %d", MSC_FLASH_DEFAULT_BAUDRATE);
    }

    // 完成Flash操作并复位目标设备
    esp_loader_flash_finish(false);
    //serial_set(true);
    gpio_set_level(GPIO_RST, false);
    //默认值：3
    // SERIAL_FLASHER_RESET_HOLD_TIME_MS
    // 这是在进行硬重置时 reset pin被置位的时间（以毫秒为单位）
    ESP_ERROR_CHECK(esp_timer_start_once(reset_timer, SERIAL_FLASHER_RESET_HOLD_TIME_MS * 500));
    return true;
}
//extern RingbufHandle_t usb_jtag_msc_rb; //
/*
* 写入扇区函数 - 处理磁盘写入请求(文件内容)
* @param start_sector 起始扇区号p
* @param buff 写入数据缓冲区
* @param sector_count 扇区数量
* @return 写入成功扇区数量
*/
// // 全局状态管理
// typedef enum {
//     FLASH_STATE_IDLE,      // 空闲状态
//     FLASH_STATE_INIT,      // 等待初始化
//     FLASH_STATE_CONNECTED, // 连接成功
// } flash_state_t;
// flash_state_t esp_msc_first_flag = FLASH_STATE_IDLE;

// #define UF2_BUFFER_SIZE (30 * 1024)
// /* 二进制信号量句柄 */
// SemaphoreHandle_t uf2_bin_sem;
// //uint32_t last_block = 0;
// char *uf2_buff = NULL;
// uint16_t uf2_buff_cnt = 0;
// typedef enum {
//     UF2_STATE_IDLE,       // 空闲状态
//     UF2_STATE_PROCESSING, // 处理中
//     UF2_STATE_TRANSIENT,  // 暂时性状态
// } uf2_state_t;
// uf2_state_t uf2_state = UF2_STATE_IDLE;
// uint32_t burn_blocks_tail=0xffffffff;
//uint32_t uf2_blocks_tail=0x0fffffff;
int bootuf2_write_sector(uint32_t start_sector, const uint8_t *buff, uint32_t sector_count)
{
    //ESP_EARLY_LOGI(TAG, "bootuf2_write_sector() invoked,start_sector=%" PRId32 ", sector_count=%" PRId32, start_sector, sector_count);
    //ESP_EARLY_LOGI("MdLink", "bootuf2_write_sector() invoked");
    if (esp_timer_is_active(reset_timer)) { // 如果目标设备正在复位
        ESP_LOGD(TAG, "Waiting for the target to reset");
        return 0;
    }
    // 检查是否为其他文件写入
    if (IS_LBA_ELSE(start_sector)) {
        uf2_block_t *p = (uf2_block_t *)buff;
        // ESP_EARLY_LOGI("MdLink", " magic0:%x, magic1:%x, magic3:%x", p->magic0, p->magic1,p->magic3);

        // 验证UF2块魔数
        //检查要写入的文件是uf2格式吗
        if (p->magic0 == UF2_FIRST_MAGIC && p->magic1 == UF2_SECOND_MAGIC && p->magic3 == UF2_FINAL_MAGIC) {
#if 0
            //读取uf2中的芯片类别()
            const char *chip_name = (p->flags & UF2_FLAG_FAMILYID_PRESENT) ? chipid_to_name(p->chip_id) : "???";

            ESP_EARLY_LOGI(TAG, "start_sector %" PRId32 ": UF2 block %" PRId32 " of %" PRId32 " for chip %s at %#08" PRIx32 " with length %" PRId32, start_sector, p->block_no, p->blocks,
                           chip_name, p->addr, p->payload_size);
            ESP_EARLY_LOGI("MdLink", "msc_last_block_written:%d", msc_last_block_written);
#endif
            // //第一个数据要连接， esp_loader_connect时间比较长
            //ESP_EARLY_LOGI("MdLink", "start_sector:%d, block_no:%d", start_sector, p->block_no);

            // if (FLASH_STATE_IDLE == esp_msc_first_flag) {
            //     esp_msc_first_flag = FLASH_STATE_INIT;
            //     xRingbufferSendFromISR(usb_jtag_msc_rb, p, UF2_BLOCK_SIZE, NULL);
            // }
            // if (FLASH_STATE_INIT == esp_msc_first_flag)
            //     return -1;
            // 设置sense data以指示设备需要初始化命令
            //ESP_EARLY_LOGI("bug", " cur_block_no:%d", p->block_no);
            //ESP_EARLY_LOGI("MdLink", "blocks:%d, block_no:%d", p->block_no, p->blocks);

            //ESP_EARLY_LOGI("MdLink", "start_sector:%d, sector_count:%d", lba, offset);

            // UF2 block detected
            /*                    chip_name 显示在UI                    */
            const char *chip_name = (p->flags & UF2_FLAG_FAMILYID_PRESENT) ? chipid_to_name(p->chip_id) : "???";
            //ESP_LOGD(TAG, "LBA %" PRId32 ": UF2 block %" PRId32 " of %" PRId32 " for chip %s at %#08" PRIx32 " with length %" PRId32, lba, p->block_no, p->blocks,
            //        chip_name, p->addr, p->payload_size);
            // if (0==msc_last_block_written)
            // {
            //     uf2_blocks_tail = p->blocks-1;
            // }

            //ESP_EARLY_LOGI("MdLink", "block_no:%d,blocks:%d", p->block_no, p->blocks);
            // Not connected to chip, initialize
            if (msc_last_block_written == -1) {
                if (!init_flash(p->chip_id)) {
                    ESP_LOGE(TAG, "Failed to initialize flash");
                    abort();
                }
            }
            // The block number is not sequential, flush the buffer
            else if (p->block_no - 1 != msc_last_block_written) {
                if (!handle_data(0, NULL, 0, true)) {
                    ESP_LOGE(TAG, "Failed to flush buffer");
                    abort();
                }
            }

            const uint32_t real_payload_size = (p->flags & UF2_FLAG_MD5_PRESENT) ? (UF2_DATA_SIZE - UF2_MD5_SIZE) : UF2_DATA_SIZE;
            if (!handle_data(p->addr, p->data, real_payload_size, false)) {
                ESP_LOGE(TAG, "Failed to handle data");
                abort();
            }
            msc_last_block_written = p->block_no;
            // if (msc_last_block_written>200)
            // {
            //     if(msc_last_block_written==p->blocks-1)
            //         tud_msc_write10_complete_cb();
            // }
            //if (last_block == p->block_no) {
            // switch (uf2_state) {
            //     case UF2_STATE_IDLE:
            //         memcpy(uf2_buff + uf2_buff_cnt * UF2_BLOCK_SIZE, p, UF2_BLOCK_SIZE);
            //         uf2_buff_cnt++;
            //         if ((uf2_buff_cnt >= UF2_BUFFER_SIZE / UF2_BLOCK_SIZE) || p->block_no == p->blocks-1) {
            //             ESP_EARLY_LOGI("MdLink", "UF2_STATE_TRANSIENT blocks :%d", p->blocks);
            //             uf2_state = UF2_STATE_TRANSIENT;
            //         }
            //         break;
            //     case UF2_STATE_PROCESSING:
            //         ESP_EARLY_LOGE("MdLink", "发送的无效");
            //         return 0xaa;
            //     case UF2_STATE_TRANSIENT:
            //         xSemaphoreGiveFromISR(uf2_bin_sem, pdTRUE);
            //         uf2_state = UF2_STATE_PROCESSING;
            //         return 0xaa;
            // }
            // int res = xRingbufferSendFromISR(usb_jtag_msc_rb, p, UF2_BLOCK_SIZE, NULL);
            // if (res == pdFALSE) {
            //     //ESP_EARLY_LOGI("MdLink", " cur_block_no:%d, last_block:%d", p->block_no, last_block);
            //     ESP_EARLY_LOGI("bug", "usb_jtag_msc_rb buffer full");
            //     return 0xaa;
            // }
            // last_block = p->block_no + 1;
            // ESP_EARLY_LOGI("bug", "uf2_buff_cnt=%d", uf2_buff_cnt);
            // if (msc_last_block_written == -1)
            //     return 0xaa;
            // } else if (last_block < p->block_no) {
            //     return -1;
            // }
        }
    }
    return 0;
}

// USB MSC写入完成回调 - 完成Flash烧录
void tud_msc_write10_complete_cb(void)
{
    if (msc_last_block_written != -1) { // 如果有写入操作
        ESP_EARLY_LOGI(TAG, "MSC write complete, last block written: %d", msc_last_block_written);
        if (!finish_flash()) { // 完成Flash烧录
            ESP_LOGE(TAG, "Failed to finish flash");
            abort();
        }
        //esp_msc_first_flag = FLASH_STATE_IDLE;
        msc_last_block_written = -1; // 重置最后写入块编号
        //msc_last_block_written = 0x0fffffff;
        //uf2_state = UF2_STATE_IDLE;
        //burn_blocks_tail=0xffffffff;
    }
}

// 复位定时器回调 - 复位目标设备
static void reset_timer_cb(void *arg)
{
    (void)arg;
    //复位的是USB-UART连接的设备，所以复位引脚为GPIO_RST
    gpio_set_level(GPIO_RST, true); // 释放复位引脚
    //serial_set(true);               // 启用串口
}

// 初始化复位定时器
static void init_reset_timer(void)
{
    const esp_timer_create_args_t timer_args = {
        .callback = reset_timer_cb,        // 回调函数
        .arg = NULL,                       // 无参数
        .dispatch_method = ESP_TIMER_TASK, // 任务分发方式
        .name = "msc_reset",               // 定时器名称
        .skip_unhandled_events = false,    // 不跳过未处理事件
    };
    ESP_ERROR_CHECK(esp_timer_create(&timer_args, &reset_timer)); // 创建定时器
}
// static TaskHandle_t *esp_msc_task_handle = NULL;
// //RingbufHandle_t usb_jtag_msc_rb; //
// #define USB_JTAG_MSC_RB_SIZE (1024 * 250)

// void usb_jtag_msc_task(void *pvParameters)
// {
//     uint16_t cnt = 0; //
//     uf2_block_t *p;
//     //每个数据项都是uf2_block_t 512
//     while (1) {
//         //p = (uf2_block_t *)xRingbufferReceive(usb_jtag_msc_rb, &size, portMAX_DELAY);
//         //ESP_LOGE("MdLink", "xRingbufferReceive %x", p);
//         if (xSemaphoreTake(uf2_bin_sem, portMAX_DELAY) == pdTRUE) {
//             ESP_LOGI("MdLink", "take uf2_bin_sem success ");
//             for (cnt = 0; cnt < uf2_buff_cnt; cnt++) {
//                 p = (uf2_block_t *)(uf2_buff + cnt * UF2_BLOCK_SIZE);
//                 ESP_LOGI(TAG, " Processing block_no=%d", p->block_no);
//                 ESP_LOGI(TAG, " msc_last_block_written=%d", msc_last_block_written);
//                 if (p->blocks>100)
//                     burn_blocks_tail = p->blocks - 1;
//                 // 如果尚未连接芯片，初始化Flash
//                 if (msc_last_block_written == -1) {
//                     if (!init_flash(p->chip_id)) {
//                         ESP_LOGE(TAG, "Failed to initialize flash");
//                         //ESP_EARLY_LOGI("MdLink", "bug place 1");
//                         abort();
//                     }
//                     ESP_EARLY_LOGI("MdLink", "init_flash success burn_blocks_tail=%d", burn_blocks_tail);
//                     // esp_msc_first_flag = FLASH_STATE_CONNECTED;
//                 }
//                 // 如果块编号不连续，刷新缓冲区
//                 else if (p->block_no - 1 != msc_last_block_written) {
//                     if (!handle_data(0, NULL, 0, true)) {
//                         ESP_LOGE(TAG, "Failed to flush buffer");
//                         abort();
//                     }
//                     //ESP_EARLY_LOGI("MdLink", "bug place 3");
//                 }

//                 // 计算实际有效载荷大小(考虑MD5)
//                 const uint32_t real_payload_size = (p->flags & UF2_FLAG_MD5_PRESENT) ? (UF2_DATA_SIZE - UF2_MD5_SIZE) : UF2_DATA_SIZE;
//                 if (!handle_data(p->addr, p->data, real_payload_size, false)) {
//                     ESP_LOGE(TAG, "Failed to handle data");
//                     abort();
//                 }
//                 msc_last_block_written = p->block_no; // 更新最后写入块编号
//                 if (msc_last_block_written == burn_blocks_tail)
//                     tud_msc_write10_complete_cb();
//                 //ESP_LOGI(TAG, "vRingbufferReturnItem block_no =%d", p->block_no);
//                 //ESP_LOGE("MdLink", "vRingbufferReturnItem %x", p);
//                 //vRingbufferReturnItem(usb_jtag_msc_rb, p);
//             }
//             uf2_buff_cnt = 0;
//             uf2_state = UF2_STATE_IDLE;

//         } else {
//             ESP_LOGE(TAG, "Take uf2_bin_sem failed");
//             abort();
//         }
//     }
// }
// MSC初始化函数
void msc_init(void)
{
    // 设置卷标
    char volume_label[FAT_VOLUME_NAME_SIZE + 1] = BRIDGE_MSC_VOLUME_LABEL; // +1因为配置值以0结尾
    // 用空格填充卷标到FAT_VOLUME_NAME_SIZE长度
    memset(volume_label + strlen(BRIDGE_MSC_VOLUME_LABEL), ' ',
           FAT_VOLUME_NAME_SIZE - strlen(BRIDGE_MSC_VOLUME_LABEL));
    memcpy(msc_disk_boot_sector.volume, volume_label, FAT_VOLUME_NAME_SIZE);
    memcpy(msc_disk_root_directory_sector0, volume_label, FAT_VOLUME_NAME_SIZE);

    // 调试信息 - 打印磁盘数据结构
    ESP_LOG_BUFFER_HEXDUMP("boot", &msc_disk_boot_sector, sizeof(msc_boot_sector_t), ESP_LOG_DEBUG);
    ESP_LOG_BUFFER_HEXDUMP("fat", msc_disk_fat_table_sector0, sizeof(msc_disk_fat_table_sector0), ESP_LOG_DEBUG);
    ESP_LOG_BUFFER_HEXDUMP("root", msc_disk_root_directory_sector0, sizeof(msc_disk_root_directory_sector0), ESP_LOG_DEBUG);
    ESP_LOGI(TAG, "MSC disk RAM usage: %d bytes", sizeof(msc_boot_sector_t) + sizeof(msc_disk_fat_table_sector0) + sizeof(msc_disk_root_directory_sector0) + sizeof(msc_disk_readme_sector0));
    init_reset_timer(); // 初始化复位定时器

    // /* 创建二进制信号量 */
    // uf2_bin_sem = xSemaphoreCreateBinary();
    // if (!uf2_buff)
    //     uf2_buff = malloc(UF2_BUFFER_SIZE);
    //usb_jtag_msc_rb = xRingbufferCreate(USB_JTAG_MSC_RB_SIZE, RINGBUF_TYPE_NOSPLIT);
    //int id = esp_cpu_get_core_id();
    //ESP_LOGE(TAG, "core id:%d", id);
    //xTaskCreatePinnedToCore(usb_jtag_msc_task, "usb_jtag_msc_task", 3072, NULL, 12, esp_msc_task_handle, 1);
}